const path = require('path')
// node 核心模块 进程对象
const os = require('os')
// 获取进程数量
const threads = os.cpus().length
// 创建html文件
const HtmlWebpackPlugin = require('html-webpack-plugin')
// css样式抽离单独文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// css压缩
const CssMinimiterWebpackPlugin = require('css-minimizer-webpack-plugin')
// eslint
const EslintWebpackPlugin = require('eslint-webpack-plugin')
// 压缩js
const TerserWebpackPlugin = require('terser-webpack-plugin')
// 相对路径改绝对路径
const pathResolve = pathStr => path.resolve(__dirname, pathStr)

// 样式处理公共方法
const getStyleLoader = (module = false, pre) => {
    return [
        MiniCssExtractPlugin.loader,
        {
            loader: 'css-loader',
            // css 模块化处理
            options: module ? {
                modules: true,
                importLoaders: 1
            } : {}
        },
        {
            // css兼容处理，能解决绝大多数兼容性问题
            // 配合 package.json 中 broserslist 指定兼容性
            loader: 'postcss-loader',
            options: {
                postcssOptions: {
                    plugins: ['postcss-preset-env']
                }
            }
        },
        pre
    ].filter(Boolean)
}

module.exports = {
    entry: pathResolve('../src/index.js'),
    output: {
        // 打包路径
        path: pathResolve('../dist'),
        // 主入口命名
        filename: 'static/js/[name].js',
        // js分割文件输出路径
        chunkFilename: 'static/js/[name]_chunk_[hash:6].js',
        // 静态资源输出地址
        assetModuleFilename: 'static/file/[name_][hash:6][ext]',
        // 清除上次打包文件
        clean: true
    },
    module: {
        rules: [
            {
                // 每个文件只能被其中一个 loader 处理
                oneOf: [
                    // css样式
                    {
                        test: /\.css$/,
                        exclude: [/node_modules/, /\.module.css$/],
                        use: getStyleLoader(false)
                    },
                    {
                        test: /\.module.css$/,
                        exclude: /node_modules/,
                        use: getStyleLoader(true)
                    },
                    {
                        test: /\.less$/,
                        exclude: [/node_modules/, /\.module.less$/],
                        use: getStyleLoader(false, 'less-loader')
                    },
                    {
                        test: /\.module.less$/,
                        exclude: /node_modules/,
                        use: getStyleLoader(true, 'less-loader')
                    },
                    {
                        test: /\.s[ac]ss$/,
                        exclude: [/node_modules/, /\.module.s[ac]ss$/],
                        use: getStyleLoader(false, 'sass-loader')
                    },
                    {
                        test: /\.module.s[ac]ss$/,
                        exclude: /node_modules/,
                        use: getStyleLoader(true, 'sass-loader')
                    },
                    // img资源
                    {
                        test: /\.(png|svg|jpe?g|gif)$/,
                        type: 'asset',
                        parser: {
                            // 小于10kb 图片被转成 base64
                            dataUrlCondition: {
                                maxSize: 20 * 1024
                            }
                        },
                        generator: {
                            // 图片输出路径
                            filename: 'static/img/[name]_[hash:6][ext]'
                        }
                    },
                    // icon图标
                    {
                        test: /\.(ttf|woff2?)$/,
                        type: 'asset/resource',
                        generator: {
                            // 文件输出路径
                            filename: 'static/font/[name]_[hash:6][ext]'
                        }
                    },
                    // es6 转 es5
                    // 创建 babel.config.js 文件
                    {
                        test: '/\.js/',
                        exclude: /node_modules/,
                        use: [
                            {
                                // 开启多进程
                                loader: 'thread-loader',
                                options: {
                                    // 进程数量
                                    works: threads
                                }
                            },
                            {
                                loader: 'babel-loader',
                                options: {
                                    // 开启 babel 缓存
                                    cacheDirectory: process.env.NODE_ENV === 'development',
                                    // 关闭缓存文件压缩
                                    cacheCompression: false,
                                    // 公共方法避免重复打包，减少代码体积
                                    plugins: ['@babel/plugin-transform-runtime']
                                }
                            }
                        ]
                    }
                ]
            }
        ]
    },
    plugins: [
        // 配置页面
        new HtmlWebpackPlugin({
            // 页面标题
            title: 'webpack-dome',
            // 页面命名
            filename: 'index.html',
            // 页面模板路径
            template: pathResolve('../public/index.html'),
            // favicon 路径
            favicon: pathResolve('../public/favicon.ico'),
            // script 插入位置
            inject: 'body'
        }),
        // css 文件抽离
        new MiniCssExtractPlugin({
            filename: 'static/css/[name].css',
            chunkFilename: 'static/css/[name].chunk.css'
        }),
        // eslint配置
        new EslintWebpackPlugin({
            // 检测文件
            // 创建 eslintrc.js 文件
            context: pathResolve('../src'),
            exclude: 'node_modules',
            // 开启缓存
            cache: process.env.NODE_ENV === 'development',
            // 缓存目录
            cacheLocation: pathResolve('../node_modules/.cache/eslint'),
            // 开启多进程，设置进程数量
            threads
        }),
        
    ],
    optimization: {
        minimizer: [
            // css 压缩
            new CssMinimiterWebpackPlugin(),
            // 压缩 js
            new TerserWebpackPlugin({
                // 开启多进程，设置进程数量
                parallel: threads
            })
        ],
        // 代码分割配置
        splitChunks: {
            chunks: 'all'
        }
    }
}